/** @file
  Unit tests of Base64 conversion APIs in BaseLib.

  Copyright (C) Microsoft Corporation.
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UnitTestLib.h>

#define UNIT_TEST_APP_NAME     "BaseLib Unit Test Application"
#define UNIT_TEST_APP_VERSION  "1.0"

/**
  RFC 4648  https://tools.ietf.org/html/rfc4648 test vectors

  BASE64("") = ""
  BASE64("f") = "Zg=="
  BASE64("fo") = "Zm8="
  BASE64("foo") = "Zm9v"
  BASE64("foob") = "Zm9vYg=="
  BASE64("fooba") = "Zm9vYmE="
  BASE64("foobar") = "Zm9vYmFy"

  The test vectors are using ascii strings for the binary data
 */

typedef struct {
    CHAR8      *TestInput;
    CHAR8      *TestOutput;
    EFI_STATUS  ExpectedStatus;
    VOID       *BufferToFree;
    UINTN       ExpectedSize;
} BASIC_TEST_CONTEXT;

#define B64_TEST_1     ""
#define BIN_TEST_1     ""

#define B64_TEST_2     "Zg=="
#define BIN_TEST_2     "f"

#define B64_TEST_3     "Zm8="
#define BIN_TEST_3     "fo"

#define B64_TEST_4     "Zm9v"
#define BIN_TEST_4     "foo"

#define B64_TEST_5     "Zm9vYg=="
#define BIN_TEST_5     "foob"

#define B64_TEST_6     "Zm9vYmE="
#define BIN_TEST_6     "fooba"

#define B64_TEST_7     "Zm9vYmFy"
#define BIN_TEST_7     "foobar"

// Adds all white space - also ends the last quantum with only spaces afterwards
#define B64_TEST_8_IN   " \t\v  Zm9\r\nvYmFy \f  "
#define BIN_TEST_8      "foobar"

// Not a quantum multiple of 4
#define B64_ERROR_1  "Zm9vymFy="

// Invalid characters in the string
#define B64_ERROR_2  "Zm$vymFy"

// Too many '=' characters
#define B64_ERROR_3 "Z==="

// Poorly placed '='
#define B64_ERROR_4 "Zm=vYmFy"

#define MAX_TEST_STRING_SIZE (200)

// ------------------------------------------------ Input----------Output-----------Result-------Free--Expected Output Size
static BASIC_TEST_CONTEXT    mBasicEncodeTest1  = {BIN_TEST_1,     B64_TEST_1,      EFI_SUCCESS, NULL, sizeof(B64_TEST_1)};
static BASIC_TEST_CONTEXT    mBasicEncodeTest2  = {BIN_TEST_2,     B64_TEST_2,      EFI_SUCCESS, NULL, sizeof(B64_TEST_2)};
static BASIC_TEST_CONTEXT    mBasicEncodeTest3  = {BIN_TEST_3,     B64_TEST_3,      EFI_SUCCESS, NULL, sizeof(B64_TEST_3)};
static BASIC_TEST_CONTEXT    mBasicEncodeTest4  = {BIN_TEST_4,     B64_TEST_4,      EFI_SUCCESS, NULL, sizeof(B64_TEST_4)};
static BASIC_TEST_CONTEXT    mBasicEncodeTest5  = {BIN_TEST_5,     B64_TEST_5,      EFI_SUCCESS, NULL, sizeof(B64_TEST_5)};
static BASIC_TEST_CONTEXT    mBasicEncodeTest6  = {BIN_TEST_6,     B64_TEST_6,      EFI_SUCCESS, NULL, sizeof(B64_TEST_6)};
static BASIC_TEST_CONTEXT    mBasicEncodeTest7  = {BIN_TEST_7,     B64_TEST_7,      EFI_SUCCESS, NULL, sizeof(B64_TEST_7)};
static BASIC_TEST_CONTEXT    mBasicEncodeError1 = {BIN_TEST_7,     B64_TEST_1,      EFI_BUFFER_TOO_SMALL, NULL, sizeof(B64_TEST_7)};

static BASIC_TEST_CONTEXT    mBasicDecodeTest1  = {B64_TEST_1,     BIN_TEST_1,      EFI_SUCCESS, NULL, sizeof(BIN_TEST_1)-1};
static BASIC_TEST_CONTEXT    mBasicDecodeTest2  = {B64_TEST_2,     BIN_TEST_2,      EFI_SUCCESS, NULL, sizeof(BIN_TEST_2)-1};
static BASIC_TEST_CONTEXT    mBasicDecodeTest3  = {B64_TEST_3,     BIN_TEST_3,      EFI_SUCCESS, NULL, sizeof(BIN_TEST_3)-1};
static BASIC_TEST_CONTEXT    mBasicDecodeTest4  = {B64_TEST_4,     BIN_TEST_4,      EFI_SUCCESS, NULL, sizeof(BIN_TEST_4)-1};
static BASIC_TEST_CONTEXT    mBasicDecodeTest5  = {B64_TEST_5,     BIN_TEST_5,      EFI_SUCCESS, NULL, sizeof(BIN_TEST_5)-1};
static BASIC_TEST_CONTEXT    mBasicDecodeTest6  = {B64_TEST_6,     BIN_TEST_6,      EFI_SUCCESS, NULL, sizeof(BIN_TEST_6)-1};
static BASIC_TEST_CONTEXT    mBasicDecodeTest7  = {B64_TEST_7,     BIN_TEST_7,      EFI_SUCCESS, NULL, sizeof(BIN_TEST_7)-1};
static BASIC_TEST_CONTEXT    mBasicDecodeTest8  = {B64_TEST_8_IN,  BIN_TEST_8,      EFI_SUCCESS, NULL, sizeof(BIN_TEST_8)-1};

static BASIC_TEST_CONTEXT    mBasicDecodeError1 = {B64_ERROR_1,    B64_ERROR_1,     EFI_INVALID_PARAMETER, NULL, 0};
static BASIC_TEST_CONTEXT    mBasicDecodeError2 = {B64_ERROR_2,    B64_ERROR_2,     EFI_INVALID_PARAMETER, NULL, 0};
static BASIC_TEST_CONTEXT    mBasicDecodeError3 = {B64_ERROR_3,    B64_ERROR_3,     EFI_INVALID_PARAMETER, NULL, 0};
static BASIC_TEST_CONTEXT    mBasicDecodeError4 = {B64_ERROR_4,    B64_ERROR_4,     EFI_INVALID_PARAMETER, NULL, 0};
static BASIC_TEST_CONTEXT    mBasicDecodeError5 = {B64_TEST_7,     BIN_TEST_1,      EFI_BUFFER_TOO_SMALL,  NULL, sizeof(BIN_TEST_7)-1};

/**
  Simple clean up method to make sure tests clean up even if interrupted and fail
  in the middle.
**/
STATIC
VOID
EFIAPI
CleanUpB64TestContext (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  BASIC_TEST_CONTEXT  *Btc;

  Btc = (BASIC_TEST_CONTEXT *)Context;
  if (Btc != NULL) {
    //free string if set
    if (Btc->BufferToFree != NULL) {
      FreePool (Btc->BufferToFree);
      Btc->BufferToFree = NULL;
    }
  }
}

/**
  Unit test for Base64 encode APIs of BaseLib.

  @param[in]  Context    [Optional] An optional parameter that enables:
                         1) test-case reuse with varied parameters and
                         2) test-case re-entry for Target tests that need a
                         reboot.  This parameter is a VOID* and it is the
                         responsibility of the test author to ensure that the
                         contents are well understood by all test cases that may
                         consume it.

  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
                                        case was successful.
  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
**/
STATIC
UNIT_TEST_STATUS
EFIAPI
RfcEncodeTest (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  BASIC_TEST_CONTEXT  *Btc;
  CHAR8               *b64String;
  CHAR8               *binString;
  UINTN               b64StringSize;
  EFI_STATUS          Status;
  UINT8               *BinData;
  UINTN               BinSize;
  CHAR8               *b64WorkString;
  UINTN               ReturnSize;
  INTN                CompareStatus;
  UINTN               indx;

  Btc = (BASIC_TEST_CONTEXT *) Context;
  binString = Btc->TestInput;
  b64String = Btc->TestOutput;

  //
  // Only testing the the translate functionality, so preallocate the proper
  // string buffer.
  //

  b64StringSize = AsciiStrnSizeS(b64String, MAX_TEST_STRING_SIZE);
  BinSize = AsciiStrnLenS(binString, MAX_TEST_STRING_SIZE);
  BinData = (UINT8 *)  binString;

  b64WorkString = (CHAR8 *) AllocatePool(b64StringSize);
  UT_ASSERT_NOT_NULL(b64WorkString);

  Btc->BufferToFree = b64WorkString;
  ReturnSize = b64StringSize;

  Status = Base64Encode(BinData, BinSize, b64WorkString, &ReturnSize);

  UT_ASSERT_STATUS_EQUAL(Status, Btc->ExpectedStatus);

  UT_ASSERT_EQUAL(ReturnSize, Btc->ExpectedSize);

  if (!EFI_ERROR (Btc->ExpectedStatus)) {
    if (ReturnSize != 0) {
      CompareStatus = AsciiStrnCmp (b64String, b64WorkString, ReturnSize);
      if (CompareStatus != 0) {
        UT_LOG_ERROR ("b64 string compare error - size=%d\n", ReturnSize);
        for (indx = 0; indx < ReturnSize; indx++) {
          UT_LOG_ERROR (" %2.2x", 0xff & b64String[indx]);
        }
        UT_LOG_ERROR ("\n b64 work string:\n");
        for (indx = 0; indx < ReturnSize; indx++) {
          UT_LOG_ERROR (" %2.2x", 0xff & b64WorkString[indx]);
        }
        UT_LOG_ERROR ("\n");
      }
      UT_ASSERT_EQUAL (CompareStatus, 0);
    }
  }

  Btc->BufferToFree = NULL;
  FreePool (b64WorkString);
  return UNIT_TEST_PASSED;
}

/**
  Unit test for Base64 decode APIs of BaseLib.

  @param[in]  Context    [Optional] An optional parameter that enables:
                         1) test-case reuse with varied parameters and
                         2) test-case re-entry for Target tests that need a
                         reboot.  This parameter is a VOID* and it is the
                         responsibility of the test author to ensure that the
                         contents are well understood by all test cases that may
                         consume it.

  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
                                        case was successful.
  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
**/
STATIC
UNIT_TEST_STATUS
EFIAPI
RfcDecodeTest(
  IN UNIT_TEST_CONTEXT  Context
  )
{
  BASIC_TEST_CONTEXT *Btc;
  CHAR8              *b64String;
  CHAR8              *binString;
  EFI_STATUS          Status;
  UINTN               b64StringLen;
  UINTN               ReturnSize;
  UINT8              *BinData;
  UINTN               BinSize;
  INTN                CompareStatus;
  UINTN               indx;

  Btc = (BASIC_TEST_CONTEXT *)Context;
  b64String = Btc->TestInput;
  binString = Btc->TestOutput;

  //
  //  Only testing the the translate functionality
  //

  b64StringLen = AsciiStrnLenS (b64String, MAX_TEST_STRING_SIZE);
  BinSize = AsciiStrnLenS (binString, MAX_TEST_STRING_SIZE);

  BinData = AllocatePool (BinSize);
  UT_ASSERT_NOT_NULL(BinData);

  Btc->BufferToFree = BinData;
  ReturnSize = BinSize;

  Status = Base64Decode (b64String, b64StringLen, BinData, &ReturnSize);

  UT_ASSERT_STATUS_EQUAL (Status, Btc->ExpectedStatus);

  // If an error is not expected, check the results
  if (EFI_ERROR (Btc->ExpectedStatus)) {
    if (Btc->ExpectedStatus == EFI_BUFFER_TOO_SMALL) {
      UT_ASSERT_EQUAL (ReturnSize, Btc->ExpectedSize);
    }
  } else {
    UT_ASSERT_EQUAL (ReturnSize, Btc->ExpectedSize);
    if (ReturnSize != 0) {
      CompareStatus = CompareMem (binString, BinData, ReturnSize);
      if (CompareStatus != 0) {
        UT_LOG_ERROR ("bin string compare error - size=%d\n", ReturnSize);
        for (indx = 0; indx < ReturnSize; indx++) {
          UT_LOG_ERROR (" %2.2x", 0xff & binString[indx]);
        }
        UT_LOG_ERROR ("\nBinData:\n");
        for (indx = 0; indx < ReturnSize; indx++) {
          UT_LOG_ERROR (" %2.2x", 0xff & BinData[indx]);
        }
        UT_LOG_ERROR ("\n");
      }
      UT_ASSERT_EQUAL (CompareStatus, 0);
    }
  }

  Btc->BufferToFree = NULL;
  FreePool (BinData);
  return UNIT_TEST_PASSED;
}

#define SOURCE_STRING  L"Hello"

STATIC
UNIT_TEST_STATUS
EFIAPI
SafeStringContraintCheckTest (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  RETURN_STATUS  Status;
  CHAR16         Destination[20];
  CHAR16         AllZero[20];

  //
  // Zero buffer used to verify Destination is not modified
  //
  ZeroMem (AllZero, sizeof (AllZero));

  //
  // Positive test case copy source unicode string to destination
  //
  ZeroMem (Destination, sizeof (Destination));
  Status = StrCpyS (Destination, sizeof (Destination) / sizeof (CHAR16), SOURCE_STRING);
  UT_ASSERT_NOT_EFI_ERROR (Status);
  UT_ASSERT_MEM_EQUAL (Destination, SOURCE_STRING, sizeof (SOURCE_STRING));

  //
  // Positive test case with DestMax the same as Source size
  //
  ZeroMem (Destination, sizeof (Destination));
  Status = StrCpyS (Destination, sizeof (SOURCE_STRING) / sizeof (CHAR16), SOURCE_STRING);
  UT_ASSERT_NOT_EFI_ERROR (Status);
  UT_ASSERT_MEM_EQUAL (Destination, SOURCE_STRING, sizeof (SOURCE_STRING));

  //
  // Negative test case with Destination NULL
  //
  ZeroMem (Destination, sizeof (Destination));
  Status = StrCpyS (NULL, sizeof (Destination) / sizeof (CHAR16), SOURCE_STRING);
  UT_ASSERT_STATUS_EQUAL (Status, RETURN_INVALID_PARAMETER);
  UT_ASSERT_MEM_EQUAL (Destination, AllZero, sizeof (AllZero));

  //
  // Negative test case with Source NULL
  //
  ZeroMem (Destination, sizeof (Destination));
  Status = StrCpyS (Destination, sizeof (Destination) / sizeof (CHAR16), NULL);
  UT_ASSERT_STATUS_EQUAL (Status, RETURN_INVALID_PARAMETER);
  UT_ASSERT_MEM_EQUAL (Destination, AllZero, sizeof (AllZero));

  //
  // Negative test case with DestMax too big
  //
  ZeroMem (Destination, sizeof (Destination));
  Status = StrCpyS (Destination, MAX_UINTN, SOURCE_STRING);
  UT_ASSERT_STATUS_EQUAL (Status, RETURN_INVALID_PARAMETER);
  UT_ASSERT_MEM_EQUAL (Destination, AllZero, sizeof (AllZero));

  //
  // Negative test case with DestMax 0
  //
  ZeroMem (Destination, sizeof (Destination));
  Status = StrCpyS (Destination, 0, SOURCE_STRING);
  UT_ASSERT_STATUS_EQUAL (Status, RETURN_INVALID_PARAMETER);
  UT_ASSERT_MEM_EQUAL (Destination, AllZero, sizeof (AllZero));

  //
  // Negative test case with DestMax smaller than Source size
  //
  ZeroMem (Destination, sizeof (Destination));
  Status = StrCpyS (Destination, 1, SOURCE_STRING);
  UT_ASSERT_STATUS_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);
  UT_ASSERT_MEM_EQUAL (Destination, AllZero, sizeof (AllZero));

  //
  // Negative test case with DestMax smaller than Source size by one character
  //
  ZeroMem (Destination, sizeof (Destination));
  Status = StrCpyS (Destination, sizeof (SOURCE_STRING) / sizeof (CHAR16) - 1, SOURCE_STRING);
  UT_ASSERT_STATUS_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);
  UT_ASSERT_MEM_EQUAL (Destination, AllZero, sizeof (AllZero));

  //
  // Negative test case with overlapping Destination and Source
  //
  ZeroMem (Destination, sizeof (Destination));
  Status = StrCpyS (Destination, sizeof (Destination) / sizeof (CHAR16), Destination);
  UT_ASSERT_STATUS_EQUAL (Status, RETURN_ACCESS_DENIED);
  UT_ASSERT_MEM_EQUAL (Destination, AllZero, sizeof (AllZero));

  return UNIT_TEST_PASSED;
}

/**
  Initialze the unit test framework, suite, and unit tests for the
  Base64 conversion APIs of BaseLib and run the unit tests.

  @retval  EFI_SUCCESS           All test cases were dispatched.
  @retval  EFI_OUT_OF_RESOURCES  There are not enough resources available to
                                 initialize the unit tests.
**/
STATIC
EFI_STATUS
EFIAPI
UnitTestingEntry (
  VOID
  )
{
  EFI_STATUS                  Status;
  UNIT_TEST_FRAMEWORK_HANDLE  Fw;
  UNIT_TEST_SUITE_HANDLE      b64EncodeTests;
  UNIT_TEST_SUITE_HANDLE      b64DecodeTests;
  UNIT_TEST_SUITE_HANDLE      SafeStringTests;

  Fw = NULL;

  DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));

  //
  // Start setting up the test framework for running the tests.
  //
  Status = InitUnitTestFramework (&Fw, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);
  if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
      goto EXIT;
  }

  //
  // Populate the B64 Encode Unit Test Suite.
  //
  Status = CreateUnitTestSuite (&b64EncodeTests, Fw, "b64 Encode binary to Ascii string", "BaseLib.b64Encode", NULL, NULL);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for b64EncodeTests\n"));
    Status = EFI_OUT_OF_RESOURCES;
    goto EXIT;
  }

  // --------------Suite-----------Description--------------Class Name----------Function--------Pre---Post-------------------Context-----------
  AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - Empty", "Test1", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest1);
  AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - f", "Test2", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest2);
  AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - fo", "Test3", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest3);
  AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - foo", "Test4", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest4);
  AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - foob", "Test5", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest5);
  AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - fooba", "Test6", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest6);
  AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - foobar", "Test7", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest7);
  AddTestCase (b64EncodeTests, "Too small of output buffer", "Error1", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeError1);
  //
  // Populate the B64 Decode Unit Test Suite.
  //
  Status = CreateUnitTestSuite (&b64DecodeTests, Fw, "b64 Decode Ascii string to binary", "BaseLib.b64Decode", NULL, NULL);
  if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for b64Decode Tests\n"));
      Status = EFI_OUT_OF_RESOURCES;
      goto EXIT;
  }

  AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - Empty", "Test1",  RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest1);
  AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - f", "Test2",  RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest2);
  AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - fo", "Test3",  RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest3);
  AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - foo", "Test4",  RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest4);
  AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - foob", "Test5",  RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest5);
  AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - fooba", "Test6",  RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest6);
  AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - foobar", "Test7",  RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest7);
  AddTestCase (b64DecodeTests, "Ignore Whitespace test", "Test8",  RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest8);

  AddTestCase (b64DecodeTests, "Not a quantum multiple of 4", "Error1", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeError1);
  AddTestCase (b64DecodeTests, "Invalid characters in the string", "Error2", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeError2);
  AddTestCase (b64DecodeTests, "Too many padding characters", "Error3", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeError3);
  AddTestCase (b64DecodeTests, "Incorrectly placed padding character", "Error4", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeError4);
  AddTestCase (b64DecodeTests, "Too small of output buffer", "Error5", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeError5);

  //
  // Populate the safe string Unit Test Suite.
  //
  Status = CreateUnitTestSuite (&SafeStringTests, Fw, "Safe String", "BaseLib.SafeString", NULL, NULL);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for SafeStringTests\n"));
    Status = EFI_OUT_OF_RESOURCES;
    goto EXIT;
  }

  // --------------Suite-----------Description--------------Class Name----------Function--------Pre---Post-------------------Context-----------
  AddTestCase (SafeStringTests, "SAFE_STRING_CONSTRAINT_CHECK", "SafeStringContraintCheckTest", SafeStringContraintCheckTest, NULL, NULL, NULL);

  //
  // Execute the tests.
  //
  Status = RunAllTestSuites (Fw);

EXIT:
  if (Fw) {
    FreeUnitTestFramework (Fw);
  }

  return Status;
}

/**
  Standard UEFI entry point for target based unit test execution from UEFI Shell.
**/
EFI_STATUS
EFIAPI
BaseLibUnitTestAppEntry (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return UnitTestingEntry ();
}

/**
  Standard POSIX C entry point for host based unit test execution.
**/
int
main (
  int argc,
  char *argv[]
  )
{
  return UnitTestingEntry ();
}
